package com.boost.tjvm.classload;

import com.alibaba.fastjson.JSON;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

public class MyClassLoadTest {

    public static void main(String[] args) throws Exception {
        demo5();
    }


    private static List getAllSubclassOfTestInterface(Class cc) {
        Field field = null;
        Vector v = null;
        List<Class> allSubclass = new ArrayList<>();
        //ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
        Class<?> classOfClassLoader = classLoader.getClass();
        while (classOfClassLoader != ClassLoader.class) {
            classOfClassLoader = classOfClassLoader.getSuperclass();
        }
        try {
            field = classOfClassLoader.getDeclaredField("classes");
        } catch (NoSuchFieldException e) {
            throw new RuntimeException("无法获取到当前线程的类加载器的classes域!");
        }
        field.setAccessible(true);
        try {
            v = (Vector) field.get(classLoader);
        } catch (IllegalAccessException e) {
            throw new RuntimeException("无法从类加载器中获取到类属性!");
        }
        for (int i = 0; i < v.size(); ++i) {
            Class<?> c = (Class<?>) v.get(i);
            if (cc.isAssignableFrom(c)) {
                allSubclass.add(c);
            }
        }
        return allSubclass;
    }


    public void demo3() throws Exception {
        try {
            //URL url = new URL("file:/F://testGradle//");
            MyClassLoad myloader = new MyClassLoad("/");
            Class c = myloader.loadClass("com.boost.tjvm.classload.Example"); //硬盘上编译后的jar文件


            Thread.currentThread().setContextClassLoader(myloader);
            System.out.println("----------");
            Object o = c.newInstance();
            //((com.tc.test)o).sey();
            Method demo = o.getClass().getMethod("demo");
            demo.invoke(o);

            System.out.println(o.getClass());
            List allSubclassOfTestInterface = getAllSubclassOfTestInterface(o.getClass());
            System.out.println(Thread.currentThread().getName() + JSON.toJSONString(allSubclassOfTestInterface));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    public static void demo4() throws Exception {
        //class path
        URL url = new URL("file:/E://git//my//boost//tjvm//out//production//classes//");
        MyUrlClassLoad myUrlClassLoad = new MyUrlClassLoad(new URL[]{url});
        Class c = myUrlClassLoad.loadClass("com.boost.tjvm.classload.Example"); //硬盘上编译后的jar文件

        Thread.currentThread().setContextClassLoader(myUrlClassLoad);

        Object o = c.newInstance();
        //((com.tc.test)o).sey();
        Method demo = o.getClass().getMethod("demo");
        demo.invoke(o);

        System.out.println(o.getClass());
        List allSubclassOfTestInterface = getAllSubclassOfTestInterface(o.getClass());
        System.out.println(Thread.currentThread().getName() + JSON.toJSONString(allSubclassOfTestInterface));
    }


    /**
     * 如果当前 class path 中包含引用中的类, com.boost.tjvm.classload.Example  那么或走 AppClassLoader 加载类
     */
    public static void demo5() throws Exception {
        //class path
        URL url = new URL("file:/F://tmp//");
        MyUrlClassLoad myUrlClassLoad = new MyUrlClassLoad(new URL[]{url});
        Class c = myUrlClassLoad.loadClass("com.boost.tjvm.classload.Example"); //硬盘上编译后的jar文件

        Object o = c.newInstance();
        //((com.tc.test)o).sey();
        Method demo = o.getClass().getMethod("demo");
        demo.invoke(o);

        System.out.println(o.getClass());
        List allSubclassOfTestInterface = getAllSubclassOfTestInterface(o.getClass());
        System.out.println(Thread.currentThread().getName() + JSON.toJSONString(allSubclassOfTestInterface));
    }


}
